package cn.nebula.music.service;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.nebula.music.dao.CommentDAO;
import cn.nebula.music.dao.SonglistDAO;
import cn.nebula.music.dao.UserAlbumDAO;
import cn.nebula.music.dao.UserCombinationDAO;
import cn.nebula.music.dao.UserDAO;
import cn.nebula.music.dao.UserSingerDAO;
import cn.nebula.music.dao.UserSonglistDAO;
import cn.nebula.music.domain.Album;
import cn.nebula.music.domain.Combination;
import cn.nebula.music.domain.Comment;
import cn.nebula.music.domain.Picture;
import cn.nebula.music.domain.Role;
import cn.nebula.music.domain.Singer;
import cn.nebula.music.domain.Songlist;
import cn.nebula.music.domain.User;
import cn.nebula.music.domain.UserAlbum;
import cn.nebula.music.domain.UserCombination;
import cn.nebula.music.domain.UserSinger;
import cn.nebula.music.domain.UserSonglist;
import cn.nebula.music.utils.MD5Utils;

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDAO userDAO;

	@Autowired
	private CommentDAO commentDAO;

	@Autowired
	private SonglistDAO songlistDAO;

	@Autowired
	private UserAlbumDAO userAlbumDAO;

	@Autowired
	private UserCombinationDAO userCombinationDAO;

	@Autowired
	private UserSingerDAO userSingerDAO;

	@Autowired
	private UserSonglistDAO userSonglistDAO;

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void addUser(User user) throws Exception {
		user.setPassword(MD5Utils.encrypt(user.getPassword()));
		userDAO.addUser(user);
		Set<Comment> comments = user.getComments();
		if (comments != null) {
			for (Comment comment : comments) {
				Comment comment1 = commentDAO.findCommentById(comment.getId());
				comment1.setUser(user);
				commentDAO.updateComment(comment1);
			}
		}
		Set<Album> albums = user.getAlbums();
		if (albums != null) {
			for (Album album : albums) {
				UserAlbum ua = new UserAlbum();
				ua.setAlbum(album.getId());
				ua.setUser(user.getId());
				userAlbumDAO.addUserAlbum(ua);
			}
		}
		Set<Combination> combinations = user.getCombinations();
		if (combinations != null) {
			for (Combination combination : combinations) {
				UserCombination uc = new UserCombination();
				uc.setCombination(combination.getId());
				uc.setUser(user.getId());
				userCombinationDAO.addUserCombination(uc);
			}
		}
		Set<Singer> singers = user.getSingers();
		if (singers != null) {
			for (Singer singer : singers) {
				UserSinger us = new UserSinger();
				us.setSinger(singer.getId());
				us.setUser(user.getId());
				userSingerDAO.addUserSinger(us);
			}
		}
		Set<Songlist> ownedSonglists = user.getOwnedSonglists();
		if (ownedSonglists != null) {
			for (Songlist songlist : ownedSonglists) {
				Songlist songlist1 = songlistDAO.findSonglistById(songlist.getId());
				songlist1.setUser(user);
				songlistDAO.updateSonglist(songlist1);
			}
		}
		Set<Songlist> likeSonglists = user.getLikeSonglists();
		if (likeSonglists != null) {
			for (Songlist songlist : likeSonglists) {
				UserSonglist us = new UserSonglist();
				us.setSonglist(songlist.getId());
				us.setUser(user.getId());
				userSonglistDAO.addUserSonglist(us);
			}
		}

	}

	@Override
	public User findUserById(int id) throws Exception {
		return userDAO.findUserById(id);
	}

	@Override
	public Set<User> findAllUsers() throws Exception {
		return userDAO.findAllUsers();
	}

	@Override
	public Set<User> findAllUsersOfBT() throws Exception {
		return userDAO.findAllUsersOfBT();
	}

	@Override
	public Set<User> findAllUsersWP() throws Exception {
		return userDAO.findAllUsersWP();
	}

	@Override
	public User findUserByUsername(String username) throws Exception {
		return userDAO.findUserByUsername(username);
	}

	@Override
	public User findUserByPhone(String phone) throws Exception {
		return userDAO.findUserByPhone(phone);
	}

	@Override
	public User findUserByEmail(String email) throws Exception {
		return userDAO.findUserByEmail(email);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateUser(User user) throws Exception {
		userDAO.updateUser(user);
		Boolean isModify = false;
		int size1 = 0;// 更改前的数量
		int size2 = 0;// 更改后的数量
		Set<Album> albums1 = findUserById(user.getId()).getAlbums();
		Set<Album> albums2 = user.getAlbums();
		if (albums1 != null) {
			size1 = albums1.size();
		}
		if (albums2 != null) {
			size2 = albums2.size();
		}
		if (size1 == size2) {
			if (!albums1.toString().equals(albums2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Album album : albums1) {
				UserAlbum ua = new UserAlbum();
				ua.setAlbum(album.getId());
				ua.setUser(user.getId());
				userAlbumDAO.deleteUserAlbum(ua);
			}
			for (Album album : albums2) {
				UserAlbum ua = new UserAlbum();
				ua.setAlbum(album.getId());
				ua.setUser(user.getId());
				userAlbumDAO.addUserAlbum(ua);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Combination> combinations1 = findUserById(user.getId()).getCombinations();
		Set<Combination> combinations2 = user.getCombinations();
		if (combinations1 != null) {
			size1 = combinations1.size();
		}
		if (combinations2 != null) {
			size2 = combinations2.size();
		}
		if (size1 == size2) {
			if (!combinations1.toString().equals(combinations2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Combination combination : combinations1) {
				UserCombination uc = new UserCombination();
				uc.setCombination(combination.getId());
				uc.setUser(user.getId());
				userCombinationDAO.deleteUserCombination(uc);
			}
			for (Combination combination : combinations2) {
				UserCombination uc = new UserCombination();
				uc.setCombination(combination.getId());
				uc.setUser(user.getId());
				userCombinationDAO.addUserCombination(uc);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Singer> singers1 = findUserById(user.getId()).getSingers();
		Set<Singer> singers2 = user.getSingers();
		if (singers1 != null) {
			size1 = singers1.size();
		}
		if (singers2 != null) {
			size2 = singers2.size();
		}
		if (size1 == size2) {
			if (!singers1.toString().equals(singers2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Singer singer : singers1) {
				UserSinger us = new UserSinger();
				us.setSinger(singer.getId());
				us.setUser(user.getId());
				userSingerDAO.deleteUserSinger(us);
			}
			for (Singer singer : singers2) {
				UserSinger us = new UserSinger();
				us.setSinger(singer.getId());
				us.setUser(user.getId());
				userSingerDAO.addUserSinger(us);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Songlist> ownedSonglists1 = findUserById(user.getId()).getOwnedSonglists();
		Set<Songlist> ownedSonglists2 = user.getOwnedSonglists();
		if (ownedSonglists1 != null) {
			size1 = ownedSonglists1.size();
		}
		if (ownedSonglists2 != null) {
			size2 = ownedSonglists2.size();
		}
		if (size1 == size2) {
			if (!ownedSonglists1.toString().equals(ownedSonglists2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Songlist songlist : ownedSonglists1) {
				Songlist songlist1 = songlistDAO.findSonglistById(songlist.getId());
				songlist1.setUser(null);
				songlistDAO.updateSonglist(songlist1);
			}
			for (Songlist songlist : ownedSonglists2) {
				Songlist songlist1 = songlistDAO.findSonglistById(songlist.getId());
				songlist1.setUser(user);
				songlistDAO.updateSonglist(songlist1);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Songlist> likeSonglists1 = findUserById(user.getId()).getLikeSonglists();
		Set<Songlist> likeSonglists2 = user.getLikeSonglists();
		if (likeSonglists1 != null) {
			size1 = likeSonglists1.size();
		}
		if (likeSonglists2 != null) {
			size2 = likeSonglists2.size();
		}
		if (size1 == size2) {
			if (!likeSonglists1.toString().equals(likeSonglists2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Songlist songlist : likeSonglists1) {
				UserSonglist us = new UserSonglist();
				us.setSonglist(songlist.getId());
				us.setUser(user.getId());
				userSonglistDAO.deleteUserSonglist(us);

			}
			for (Songlist songlist : likeSonglists2) {
				UserSonglist us = new UserSonglist();
				us.setSonglist(songlist.getId());
				us.setUser(user.getId());
				userSonglistDAO.addUserSonglist(us);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Comment> comments1 = findUserById(user.getId()).getComments();
		Set<Comment> comments2 = user.getComments();
		if (comments1 != null) {
			size1 = comments1.size();
		}
		if (comments2 != null) {
			size2 = comments2.size();
		}
		if (size1 == size2) {
			if (!comments1.toString().equals(comments2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Comment comment : comments1) {
				Comment comment1 = commentDAO.findCommentById(comment.getId());
				comment1.setUser(null);
				commentDAO.updateComment(comment1);
			}
			for (Comment comment : comments2) {
				Comment comment1 = commentDAO.findCommentById(comment.getId());
				comment1.setUser(user);
				commentDAO.updateComment(comment1);
			}
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean loginValidate(User user) throws Exception {
		boolean result = false;
		if (user != null && user.getPassword() != null) {
			if (user.getUsername() != null || user.getEmail() != null || user.getPhone() != null) {
				for (User existUser : userDAO.findAllUsersOfBT()) {
					if (existUser.getUsername().equals(user.getUsername())
							|| (existUser.getEmail() != null && existUser.getEmail().equals(user.getEmail()))
							|| (existUser.getPhone() != null && existUser.getPhone().equals(user.getPhone()))) {
						try {
							if (existUser.getPassword().equals(MD5Utils.encrypt(user.getPassword()))) {
								result = true;
								break;
							}
						} catch (NoSuchAlgorithmException e) {
							e.printStackTrace();
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		return result;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public String registerValidate(User user) throws Exception {
		String result = null;
		if (user != null && user.getPassword() != null) {
			if (user.getUsername() != null || user.getEmail() != null || user.getPhone() != null) {
				for (User existUser : userDAO.findAllUsersOfBT()) {
					System.out.println(existUser);
					if (existUser.getUsername() != null && existUser.getUsername().equals(user.getUsername())) {
						result = "该用户名已存在！";
						System.out.println(result);
						break;
					} else if (existUser.getEmail() != null && existUser.getEmail().equals(user.getEmail())) {
						result = "该邮箱已存在！";
						break;
					} else if (existUser.getPhone() != null && existUser.getPhone().equals(user.getPhone())) {
						result = "该电话号码已存在！";
						break;
					} else {
						result = "注册成功！";
					}
				}
			}
			if (result.equals("注册成功！")) {
				String password = null;
				try {
					password = MD5Utils.encrypt(user.getPassword());
				} catch (NoSuchAlgorithmException e) {
					e.printStackTrace();
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
				Role role = new Role();
				role.setId(1);
				Picture picture = new Picture();
				picture.setId(0);
				user.setRole(role);
				user.setPicture(picture);
				user.setPassword(password);
				userDAO.addUser(user);
			}
		}
		return result;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public Set<User> findUsersByRole(Integer roleId) throws Exception {
		return userDAO.findUsersByRole(roleId);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void deleteUserById(Integer id) throws Exception {
		userAlbumDAO.deleteUserAlbumByUserId(id);
		userCombinationDAO.deleteUserCombinationByUserId(id);
		userSingerDAO.deleteUserSingerByUserId(id);
		userSonglistDAO.deleteUserSonglistByUserId(id);
		for (Songlist songlist : songlistDAO.findAllSonglists()) {
			if (songlist.getUser() != null && songlist.getUser().getId().equals(id)) {
				songlist.setUser(null);
				songlistDAO.updateSonglist(songlist);
			}
		}
		for (Comment comment : commentDAO.findAllComments()) {
			if (comment.getUser() != null && comment.getUser().getId().equals(id)) {
				comment.setUser(null);
				commentDAO.updateComment(comment);
			}
		}
		userDAO.deleteUserById(id);
	}

}
